package haxeframe.loading;

import flash.events.ProgressEvent;
import flash.utils.ByteArray;
import haxeframe.Globals;
import haxeframe.loading.LoadManager;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.media.Sound;
import flash.net.URLLoader;

class LoadObject
{
	private var complete:Bool = false;

	public var channel:String;
	public var data:ByteArray;

	private var _loader:Dynamic;
	public var loader(get,never):Dynamic;
	public function get_loader():Dynamic
	{
		return _loader;
	}

	private var _url:String;
	public var url(get,never):String;
	public function get_url():String
	{
		return _url;
	}

	private var _file:Dynamic;
	public var file(get,set):Dynamic;
	public function get_file():Dynamic
	{
		return _file;
	}
	public function set_file(value:Dynamic):Dynamic
	{
		_file = value;
		if(_file != null){
			if(!complete){
				onFileComplete();
				complete = true;
			}
		}
		return _file;
	}

	private var _queue:String;
	public var queue(get,never):String;
	public function get_queue():String
	{
		return _queue;
	}

	private var _childQueue:String;
	public var childQueue(get,never):String;
	public function get_childQueue():String
	{
		if(_childQueue == null){
			return _queue;
		}
		return _childQueue;
	}

	private var _name:String;
	public var name(get,never):String;
	public function get_name():String
	{
		return _name;
	}

	private var _onLoadCallback:LoadObject->Void;
	public var onLoadCallback(get,never):LoadObject->Void;
	public function get_onLoadCallback():LoadObject->Void
	{
		return _onLoadCallback;
	}

	private var _callbackScope:Dynamic;
	public var callbackScope(get,never):Dynamic;
	public function get_callbackScope():Dynamic
	{
		return _callbackScope;
	}

	public function new(name:String, url:String, loader:Dynamic=null, queue:String=null, onLoadCallback:LoadObject->Void=null, callbackScope:Dynamic=null, childQueue:String=null)
	{
		_name = name;
		_url = url;
		_loader = loader;
		_queue = queue;
		_childQueue = childQueue;
		_onLoadCallback = onLoadCallback;
		_callbackScope = callbackScope;
		if(_loader != null){
			LoadManager.scope.addEventListener(Event.ENTER_FRAME, onFileProgress);
			_loader.addEventListener(Event.COMPLETE, onFileComplete);
			_loader.addEventListener(IOErrorEvent.IO_ERROR, LoadManager.onIOError);
			_loader.addEventListener(ErrorEvent.ERROR, LoadManager.onError);
		}
	}

	public function onFileProgress(event:Event):Void
	{
		LoadManager.onFileProgress(_loader);
	}

	private function onFileComplete(event:Event=null):Void
	{
		if(_loader != null){
			LoadManager.scope.removeEventListener(Event.ENTER_FRAME, onFileProgress);
			_loader.removeEventListener(Event.COMPLETE, onFileComplete);
			_loader.removeEventListener(IOErrorEvent.IO_ERROR, LoadManager.onIOError);
			_loader.removeEventListener(ErrorEvent.ERROR, LoadManager.onError);

			if(Std.is(_loader, URLLoader)){
				_file = _loader.data;
			} else if(Std.is(_loader, LoaderInfo)){
				_file = _loader.content;
			} else if(Std.is(_loader, Sound)){
				_file = _loader;
			}
		}

		if(_onLoadCallback != null && _callbackScope != null){
			Reflect.callMethod(_callbackScope, _onLoadCallback, [this]);
			_callbackScope = null;
			_onLoadCallback = null;
		}
		if(_file != null){
			LoadManager.onFileComplete(this);
			complete = true;
		}
	}

	public function destroy():Void
	{
		if(!complete && _loader != null){
			LoadManager.scope.removeEventListener(Event.ENTER_FRAME, onFileProgress);
			_loader.removeEventListener(Event.COMPLETE, onFileComplete);
			_loader.removeEventListener(IOErrorEvent.IO_ERROR, LoadManager.onIOError);
			_loader.removeEventListener(ErrorEvent.ERROR, LoadManager.onError);
		}
		_callbackScope = null;
		_onLoadCallback = null;
		data = null;
		_loader = null;
		file = null;
	}

}